﻿
// load server actionscript files

load("key_recogniser.asc");


/* 
* application.onAppStart:
*					is called when application load. It contains (VOD) Video-on-Demand 
* application specific initializations. 
*/
application.onAppStart = function()
{	
	// Logging
	trace("Starting VOD Service...");
	// Turning on the Authentication by default
	this.HTMLDomainsAuth =	true;
	this.SWFDomainsAuth =	true;
	
	// Populating the list of domains which are allowed to host HTML file
	// which in turn can embed a SWF to connect to this application
	this.allowedHTMLDomains = this.readValidDomains("allowedHTMLdomains.txt","HTMLDomains");

	// Populating the list of domains which are allowed to host a SWF file
	// which may connect to this application
	this.allowedSWFDomains = this.readValidDomains("allowedSWFdomains.txt", "SWFDomains");

	// Logging
	if(this.HTMLDomainsAuth){
		trace("Authentication of HTML page URL domains is enabled");
	}
	if(this.SWFDomainsAuth){
		trace("Authentication of SWF URL domains is enabled");
	}
	trace("...loading completed.");	
	
}


/*
*  application.validate:
* 				function to validate a given URL by matching through a list of
* allowed patterns.
* 
* Parameters:
* 	url:		contains the input url string.
* 	patterns:	Array; an array of permmited url patterns.
* 
* return value:
* 			true; when 'url domain" contains a listed domains as a suffix.
*  			false; otherwise.
*/

application.validate = function( url, patterns )
{
	// Convert to lower case
	url = url.toLowerCase();
	var domainStartPos = 0; // domain start position in the URL
	var domainEndPos = 0; // domain end position in the URL
	
	switch (url.indexOf( "://" ))
	{
		case 4:
			if(url.indexOf( "http://" ) ==0)
				domainStartPos = 7;
			break;
		case 5:
			if(url.indexOf( "https://" ) ==0)
				domainStartPos = 8;
			break;
	}
	if(domainStartPos == 0)
	{
		// URL must be HTTP or HTTPS protocol based
		return false;
	}
	domainEndPos = url.indexOf("/", domainStartPos);
	if(domainEndPos>0)
	{
		colonPos = url.indexOf(":", domainStartPos); 
		if( (colonPos>0) && (domainEndPos > colonPos))
		{
			// probably URL contains a port number
			domainEndPos = colonPos; // truncate the port number in the URL
		}
	}
	for ( var i = 0; i < patterns.length; i++ )
	{
		var pos = url.lastIndexOf( patterns[i]);
		if ( (pos > 0) && (pos  < domainEndPos) && (domainEndPos == (pos + patterns[i].length)) )
			return true;
	}
	return false;
}

/*
* 	application.onConnect:
* 				Implementation of the onConnect interface function (optional). 
*  it is invoked whenever a client connection request connection. VOD uses this 
*  function to authenticate the connection source domain and authorizes only 
*  for a subscriber request.
*/ 


application.onConnect = function( p_client, p_autoSenseBW )
{
	//Add security here
	p_client.writeAccess = ""; // prevents creating shared object or live streams.

	// Authenticating HTML file's domain for the request :
	// Don't call validate() when the request is from localhost 
	// or HTML Domains Authentication is off.
	if ((p_client.ip != "127.0.0.1") && application.HTMLDomainsAuth &&  !this.validate( p_client.pageUrl, this.allowedHTMLDomains ) )
	{
		trace("Authentication failed for pageurl: " + p_client.pageUrl + ", rejecting connection from "+p_client.ip);
		return false;
	}

	
	// Authenticating the SWF file's domain for the request :
	// Don't call validate() when the request is from localhost 
	// or SWF Domains Authentication is off.
	if ((p_client.ip != "127.0.0.1") && application.SWFDomainsAuth &&  !this.validate( p_client.referrer, this.allowedSWFDomains ) )
	{
		trace("Authentication failed for referrer: " + p_client.referrer + ", rejecting connection from "+p_client.ip);
		return false;
	}

	// As default, all clients are disabled to access raw audio and video and data bytes in a stream 
	// through the use of BitmapData.draw() and SoundMixer.computeSpectrum()., Please refer
	// Stream Data Access doccumentations to know flash player version requirement to support this restriction.
	// Access permissions can be allowed for all by uncommenting the following statements
	
	//p_client.audioSampleAccess = "/";
 	//p_client.videoSampleAccess = "/";
	
	
	this.acceptConnection(p_client);
	
	// Logging
	trace("Accepted a connection from IP:"+ p_client.ip 
				+ ", referrer: "+ p_client.referrer
				+ ", pageurl: "+ p_client.pageUrl);
		
	// A connection from Flash 8 & 9 FLV Playback component based client  
	// requires the following code.
		
	if (p_autoSenseBW)
			p_client.checkBandwidth();
	else
			p_client.call("onBWDone");
	
	p_client.m_z= 23936;      // constants used for key generation
	p_client.m_w= 32983;
	p_client.keyClient=0;
	p_client.keyServer=0;  //key sent by client and key generated by the server
	  
	//identification number for set interval method
	
	p_client.u_id = setInterval(key_recogniser, 3000, p_client);  // call function in 3000 milliseconds		
}



application.onDisconnect = function(p_client){
	
	trace("Connection disconnected.... ");
	clearInterval(p_client.u_id);        //clear setInterval method
}

application.onAppStop = function (info){
	trace("*** Application stopped ***");
}


/*
* Client.prototype.getPageUrl
* 				Public API to return URL of the HTML page.				
* 
*/

Client.prototype.getPageUrl = function() {
	return this.pageUrl;
}

/*
* Client.prototype.getReferrer
* 				Public API to return Domain URL of the client SWF file.				
* 
*/
Client.prototype.getReferrer = function() {
	return this.referrer;
}

/*
* Client.prototype.getStreamLength
* 				Function to return the total length of the stream				
* 
*/

Client.prototype.getStreamLength = function(p_streamName) {
	return Stream.length(p_streamName);
}



/*
* application.readValidDomains
* 			Function to read Allowed domain file 
* Parameters:
* 		fileName:
* 			name of the file in the application directory
* which contains one valid domain name per line. This file can contain
* comments followed by a '#' as the very first charector in that line. 
* a non-comment entry with a space is considered as an error case.
*  
* returns
* 		an array in which each entry contains a domain name 
* listed in the file.
*/

application.readValidDomains = function( fileName , domainsType )
{
	var domainFile = new File(fileName);
	var domainsArray = new Array();
	var index = 0;
	var lineCount = 0;
	var tempLine;
	domainFile.open("text", "read"); 
	
	// Read the file line-by-line and fill the domainsArray 
	// with valid entries
	while (domainFile.isOpen && ! domainFile.eof() )
	{
		
		tempLine = domainFile.readln();
		lineCount++;
		if( !tempLine  || tempLine.indexOf("#") == 0)
		{
			continue;
		}
		tempLine = tempLine.trim();
		if(tempLine.indexOf(" ")!=-1)
		{
			trace("undesired <space>, domain entry ignored. "+fileName+":"+(lineCount+1));
		}
		else
		{
			domainsArray[index] =  tempLine.toLowerCase();
			index++;
			
			if(tempLine == "*")
			{
				switch (domainsType){
					
					case "HTMLDomains":
						trace ("Found wildcard (*) entry: disabling authentication of HTML file domains ")	;
						application.HTMLDomainsAuth =	false;		
						break;
					
					case "SWFDomains":
						trace ("Found wildcard (*) entry: disabling authentication of SWF file domains ")	;
						this.SWFDomainsAuth =	false;		
						break;
						
					default:
						// Do nothing
						break;	
				}
			}
		}
	} // End while
	
	// Something is wrong! the domains file must be accessible.
	if( !domainFile.isOpen){
		trace("Error: could not open '"+fileName+"', rejecting all clients except localhost. ");
		
	}
	else 
	{
		domainFile.close();
	}

	return domainsArray;
}

/**
* String.prototype.trim:
* 			Function to trim spaces in start an end of an input string.
* returns:
* 		a trimmed string without any leading & ending spaces.
* 		 
*/
String.prototype.trim = function () {
	
	return this.replace(/^\s*/, "").replace(/\s*$/, "");
}